package com.kaigejava.demo.business.service;

import com.kaigejava.demo.business.common.GlobalMap;
import com.kaigejava.demo.business.enums.TypeEnum;
import com.kaigejava.demo.business.service.grab.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @BelongsProject: douyin-live-java
 * @Author: kaigejava
 * @CreateTime: 2023-11-09  15:32
 * @Description: websocket服务层
 * @Version: 1.0
 */
@Component
@Slf4j
@ServerEndpoint(value = "/dm/{type}/{roomId}/{timestamp}")
public class WebSocketService extends BaseSendMessageService {


    private static BilibiliLiveGrabService bilibiliLiveGrabService;

    private static DouYinGrabService douYinGrabService;

    private static DouYuGrabService douYuGrabService;

    private static HuYaGrabService huYaGrabService;

    @Autowired
    public void setHuYaGrabService(HuYaGrabService huYaGrabService) {
        WebSocketService.huYaGrabService = huYaGrabService;
    }

    @Autowired
    public void setDouYinGrabService(DouYuGrabService douYuGrabService) {
        WebSocketService.douYuGrabService = douYuGrabService;
    }

    @Autowired
    public void setDouYinGrabService(DouYinGrabService douYinGrabService) {
        WebSocketService.douYinGrabService = douYinGrabService;
    }

    @Autowired
    public void setBilibiliLiveGrabService(BilibiliLiveGrabService bilibiliLiveGrabService) {
        WebSocketService.bilibiliLiveGrabService = bilibiliLiveGrabService;
    }

    //前端请求时一个websocket时
    @OnOpen
    public void onOpen(Session session, @PathParam("roomId") String roomId, @PathParam("type") String type,@PathParam("timestamp") long timestamp) throws Exception {
        String socketKey = type + "_" + roomId+"_"+timestamp;
        String typeAndRoom = type + "_" + roomId;
        this.session = session;
        String message = "当前连接的系统是:" + TypeEnum.getMessageByCode(type);
        WebSocketService listenRoom =null;// GlobalMap.webSocketMap.get(socketKey);
        String wokingKey = "";
        for (Map.Entry<String, WebSocketService> stringWebSocketServiceEntry : GlobalMap.webSocketMap.entrySet()) {
            String key = stringWebSocketServiceEntry.getKey();
            if(key.contains(typeAndRoom)){
                listenRoom = stringWebSocketServiceEntry.getValue();
                wokingKey = key;
                break;
            }
            
        }
        GlobalMap.webSocketMap.put(socketKey, this);
        //同一个系统的同一个房间号，只能有一个监听者
        if(Objects.nonNull(listenRoom)){
            //获取时间
            String time = wokingKey.split("_")[2];
            Date date = new Date(Long.valueOf(time));
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String t = sdf.format(date);
            message += ".直播房间号为:"+roomId+",已经在抓取中了。上一次抓取时间为:"+t+"。请勿重复抓取";
            sendMessage(message, socketKey);
            return;
        }

        //其实这里使用策略模式更好
        if (type.equals(TypeEnum.B_STATION.getCode())) {
            //处理B站获取弹幕的
            bilibiliLiveGrabService.grab(roomId,timestamp);
        } else if (type.equals(TypeEnum.DY_STATION.getCode())) {
            //处理抖音获取弹幕的
            douYinGrabService.grab(roomId,timestamp);
        } else if (type.equals(TypeEnum.DYU_STATION.getCode())) {
            //处理斗鱼获取弹幕的
            sendMessage(message, socketKey);
            douYuGrabService.grab(roomId,timestamp);
        } else if (type.equals(TypeEnum.HY_STATION.getCode())) {
            //处理虎牙获取弹幕的
            sendMessage(message, socketKey);
            huYaGrabService.grab(roomId,timestamp);
        }
        //sendMessage(message, socketKey);
        System.out.println("【websocket消息】有新的连接,连接id" + roomId);
    }

    //前端关闭时一个websocket时
    @OnClose
    public void onClose(@PathParam("type") String type, @PathParam("roomId") String roomId) throws Exception {
        System.out.println("强制断开连接");
        if (type.equals(TypeEnum.B_STATION.getCode())) {
            //处理B站获取弹幕的
            bilibiliLiveGrabService.close(roomId);
        }else if (type.equals(TypeEnum.DY_STATION.getCode())) {
            //处理B站获取弹幕的
            douYinGrabService.close(roomId);
        } else if (type.equals(TypeEnum.DYU_STATION.getCode())) {
            //处理斗鱼获取弹幕的
            douYuGrabService.close(roomId);
        } else if (type.equals(TypeEnum.HY_STATION.getCode())) {
            //处理虎牙获取弹幕的
            huYaGrabService.close(roomId);
        }
        String typeAndRoom = type + "_" + roomId;
        //将这个房间中所有的都移除
        for (Map.Entry<String, WebSocketService> stringWebSocketServiceEntry : GlobalMap.webSocketMap.entrySet()) {
            String key = stringWebSocketServiceEntry.getKey();
            if(key.contains(typeAndRoom)){
                System.out.println("开始移除key:"+key);
                GlobalMap.webSocketMap.remove(key);
            }
        }
        System.out.println("【websocket消息】连接断开,总数:" + GlobalMap.webSocketMap.size());
    }

    //前端向后端发送消息
    @OnMessage
    public void onMessage(String message) {
        if (!message.equals("ping")) {
            System.out.println("【websocket消息】收到客户端发来的消息:" + message);
        }
    }
}
